package com.huawei.spare.part.replace.models;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonValue;
import com.huawei.spare.part.replace.models.constants.Plane;
import com.huawei.spare.part.replace.models.constants.VersionRange;
import lombok.Data;
import lombok.ToString;

import java.io.Serializable;
import java.util.List;

@Data
@ToString
public class Solution {

    Integer id;

    String model;
    List<Plane> planes;
    Serial defective;
    Serial spare;
    Boolean isStacked;

    List<String> risks;
    List<String> suggestions;
    String type;

    Prepare prepare;    // 升级前准备
    Upgrade fabric;     // 升级 Fabric 平面
    Upgrade base;       // 升级 Base 平面

    @JsonProperty("CPLD")
    Upgrade CPLD;       // 升级后 CPLD 升级
    @JsonProperty("BMC")
    Upgrade BMC;        // 升级后 BMC 升级

    String successTips;

    @Data
    @ToString
    public static class Serial implements Serializable {
        /**
         * 需要支持 +/- 闭区间，为空表示都支持？
         */
        List<Version> softwareVersions;
        List<Version> cpldVersions;
        Boolean isV5;

        public boolean containsSoftwareVersion(String softwareVersion) {
            if (this.softwareVersions == null || this.softwareVersions.size() == 0) {
                return true;
            }
            return this.softwareVersions.stream().allMatch(v -> v.contains(softwareVersion));
        }

        public boolean containsCpldVersion(String cpldVersion) {
            if (this.cpldVersions == null || this.cpldVersions.size() == 0) {
                return true;
            }
            return this.cpldVersions.stream().allMatch(v -> v.contains(cpldVersion));
        }

    }

    @Data
    @ToString
    public static class Version implements Serializable {
        String version;
        VersionRange range;

        @JsonValue
        public String value() {
            return version + range.getOp();
        }

        @JsonCreator
        public Version(String version) {
            if (version.endsWith("+")) {
                this.range = VersionRange.GE;
                this.version = version.substring(0, version.length() - 1);
            } else if (version.endsWith("-")) {
                this.range = VersionRange.LE;
                this.version = version.substring(0, version.length() - 1);
            } else {
                this.range = VersionRange.EQ;
                this.version = version;
            }
        }

        /**
         * whether the version contains target version
         *
         * @param targetVersion
         * @return
         */
        public boolean contains(String targetVersion) {
            switch (this.range) {
                case EQ:
                    return this.version.equalsIgnoreCase(targetVersion);
                case GE:
                    return this.version.toLowerCase().compareTo(targetVersion.toLowerCase()) <= 0;
                case LE:
                    return this.version.toLowerCase().compareTo(targetVersion.toLowerCase()) >= 0;
            }
            return false;
        }
    }

    @Data
    @ToString
    public static class Prepare implements Serializable {
        Boolean ubootMode;
        Boolean upgradeCpld;
        Boolean isV5;
        String v5Tips;
        List<Handler> preHandles;
    }

    @Data
    @ToString
    public static class Upgrade implements Serializable {
        String version;
        String packageName;
        Boolean upgrade;
        List<Handler> postHandlers;
    }

    @Data
    @ToString
    public static class Handler implements Serializable {
        String when;
        String action;
        Boolean successKeyword;
    }


    public static void main(String[] args) {
        String version = "V3.12";
        System.out.println(version.compareTo("V3.11.1"));
    }

}
